<!-- 非法端口 -->
<template>
  <div class="dashboard-editor-container">
    <el-row style="background: #fff; padding: 16px;">
      <div style="display:flex;justify-content:space-between;">
        <div>
          <el-button type="primary" icon='el-icon-circle-plus-outline' @click="addClick()">添加规则</el-button>
          <span style="color:#d2d7e3;font-size:25px;margin-top:10px;padding-left:10px;">
            <el-tooltip class="item" effect="dark" placement="right">
              <i class="el-icon-question"></i>
              <div style="width: 420px;" slot="content">通过拖动表格行来重新排列顺序, 当前顺序将影响执行顺序。</div>
            </el-tooltip>
          </span>
        </div>
      </div>
      <el-table stripe border :data="tableData" class="draggable-table" row-key="RuleName"
        style="width: 100%; margin-top: 15px">
        <el-table-column label="序号" width="60" type="index"
          :index='(index) => { return (index + 1) + (this.pageNum - 1) * this.pageSize }'> </el-table-column>
        <el-table-column label="规则名称" prop="RuleName" show-overflow-tooltip width="160px"></el-table-column>
        <el-table-column label="应用对象类型" show-overflow-tooltip prop="DeviceObjType" width="120px">
          <template slot-scope="{row}">
            <span>{{ DeviceObjTypeFormatter(row) }}</span>
          </template>
        </el-table-column>
        <el-table-column label="应用对象" show-overflow-tooltip prop="DeviceObj" width="160px">
          <template slot-scope="{row}">
            <span>{{ getDeviceObjDisplay(row, DepartmentList, AssetsList) }}</span>
          </template>
        </el-table-column>
        <el-table-column label="规则生效" show-overflow-tooltip prop="IsValid" width="160px">
          <template slot-scope="{row}">
            <span style="color:#67C23A" v-if="row.IsValid === 1" type="success">生效</span>
            <span style="color:#F56C6C" v-else type="danger">停用</span>
          </template>
        </el-table-column>
        <el-table-column label="检测模式" show-overflow-tooltip prop="CheckType" width="160px">
          <template slot-scope="{row}">
            <span style="color:#67C23A" v-if="row.CheckType === 1" type="success">白名单</span>
            <span style="color:#F56C6C" v-else type="danger">黑名单</span>
          </template>
        </el-table-column>
        <el-table-column label="检测间隔" show-overflow-tooltip prop="Interval" width="160px"></el-table-column>
        <el-table-column label="扫描端口" show-overflow-tooltip prop="Port">
          <template slot-scope="scope">
            {{ formatPorts(scope.row.Port) }}
          </template>
        </el-table-column>
        <el-table-column label="备注信息" show-overflow-tooltip prop="Descp"></el-table-column>
        <el-table-column label="操作" width="150px">
          <template slot-scope="scope">
            <el-button size="mini" type="primary" @click="changeClick(scope.row, scope.$index)">修改</el-button>
            <el-button size="mini" type="danger" @click="deleteClick(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-row>
    <el-dialog top="5vh" :close-on-click-modal="false" :close-on-press-escape=false
      :title="Action === 1 ? '添加规则' : '修改规则'" :visible.sync="dialogVisible" v-el-drag-dialog width="800px">
      <el-form label-width="130px" :model="accountForm" :rules="rules" ref="accountForm">
        <el-row class="ruleMain">
          <el-divider content-position="left">基本规则内容</el-divider>
          <el-col :xs="24" :sm="24" :lg="24">
            <el-form-item label='规则名称:' prop="RuleName">
              <el-input v-model.trim="accountForm.RuleName" :disabled="Action !== 1" :maxlength="30"></el-input>
            </el-form-item>
          </el-col>
          <el-col :xs="24" :sm="24" :lg="24">
            <el-form-item label='规则状态：' prop="IsVaclid">
              <el-radio v-model="accountForm.IsValid" :label="1">正常</el-radio>
              <el-radio v-model="accountForm.IsValid" :label="0">失效</el-radio>
            </el-form-item>

          </el-col>
          <el-col :xs="24" :sm="24" :lg="24">
            <device-object-selector :form.sync="accountForm" />
          </el-col>
          <el-col :xs="24" :sm="24" :lg="24">
            <el-form-item label="备注信息" prop="Descp">
              <el-input placeholder="请输入备注" type="textarea" maxlength="50" :rows="3"
                v-model="accountForm.Descp"></el-input>
            </el-form-item>
          </el-col>
          <el-col :xs="19" :sm="19" :lg="19">
            <el-form-item label='检测间隔:' prop="Interval">
              <el-input v-model="accountForm.Interval" oninput="value=value.replace(/[^0-9]/g,'')" maxlength="6"><span
                  slot="append">秒</span></el-input>
            </el-form-item>
          </el-col>
          <el-col :xs="24" :sm="24" :lg="24">
            <el-form-item label='检测模式:' prop="CheckType">
              <el-radio v-model="accountForm.CheckType" :label="1">白名单</el-radio>
              <el-radio v-model="accountForm.CheckType" :label="0">黑名单</el-radio>
            </el-form-item>
          </el-col>
          <el-col :xs="24" :sm="24" :lg="24">
            <el-form-item prop="Port">
              <el-input placeholder="请输入扫描的端口" value="12" type="textarea" :rows="3" v-model="accountForm.Port"
                @input="validateInput"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <el-divider></el-divider>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submit()">确 定</el-button>
        <el-button type="info" @click="dialogVisible = false">取 消</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import { connrequest } from '@/api/firstPage'
import { getDeviceObjDisplay, DeviceObjTypeFormatter } from '@/utils/index.js';
import elDragDialog from '@/directive/el-drag-dialog' // base on element-ui
import Sortable from "sortablejs";
import DeviceObjectSelector from '@/components/DeviceObjectSelector'
export default {
  directives: { elDragDialog },
  components: {
    DeviceObjectSelector
  },
  data() {
    return {
      pageNum: 1,
      pageSize: 10,
      tableData: [],
      RoleList: [],
      DepartmentList: [],
      AssetsList: [],
      Action: 1,
      dialogVisible: false,
      accountForm: {
      },
      DeviceObjList: [],
      rules: {
        RuleName: [
          { required: true, message: "请输入规则名称" }
        ],
        Port: [
          {
            validator: (rule, value, callback) => {
              // 将输入按换行符拆分成数组
              if (value === undefined) {
                // 输入值为 undefined，直接返回成功
                callback();
                return;
              }
              const ports = value.split(/\n/);
              let valid = true;
              // 遍历每个端口号
              ports.forEach(port => {
                // 移除空白字符
                port = port.trim();
                // 检查是否是介于 1 到 65535 之间的整数
                const intValue = parseInt(port);
                if (isNaN(intValue) || intValue < 1 || intValue > 65535) {
                  valid = false;
                }
              });
              // 根据验证结果调用 callback
              if (valid) {
                callback();
              } else {
                callback(new Error("端口输入介于 1 到 65535 之间的整数"));
              }
            },
            trigger: 'blur', // 触发时机，可以根据需要调整
            message: "端口输入介于1 到 65535 之间的整数"
          }
        ]
      }
    }
  },
  //生命周期 - 创建完成（访问当前this实例）
  created() {
    this.GetDepartment()
    this.GetDevice()
    this.getData()
  },
  //生命周期 - 挂载完成（访问DOM元素）
  mounted() {
    this.initSort();
  },
  methods: {
    DeviceObjTypeFormatter,
    getDeviceObjDisplay,
    // 获取所有部门
    async GetDepartment() {
      const res = await connrequest('GetDepartment')
      this.DepartmentList = res.Data
    },
    // 获取所有资产
    async GetDevice() {
      const data = {
        Paging: {
          QueryPageNo: 1,
          QueryPageLength: 100000
        },
      }
      const res = await connrequest('GetDevice', data)
      this.AssetsList = res.Data
    },
    initSort() {
      const el = document.querySelectorAll('.el-table__body-wrapper > table > tbody')[0]
      // 根据具体需求配置options配置项
      const sortable = new Sortable(el, {
        animation: 500, // 拖拽时的动画时长
        onEnd: async (evt) => { // 监听拖动结束事件
          // 下面将拖拽后的顺序进行修改
          const currRow = this.tableData.splice(evt.oldIndex, 1)[0]
          this.tableData.splice(evt.newIndex, 0, currRow)
          const newData = []
          this.tableData.forEach((item, index) => {
            newData[index] = {
              id: item.id,
              rank: index + 1
            }
          })
          const data = {
            Data: {
              OpFile: 6,
              List: [...this.tableData]
            }
          }
          const res = await connrequest('ReorderList', data)
          if (res.Status.StatusCode === 0) {
            this.$message.success('排序成功')
            this.getData()
          }
        }
      })
    },
    async getData() {
      const res = await connrequest('GetListenPortRule')
      this.tableData = res.Data
    },
    formatPorts(ports) {
      if (Array.isArray(ports)) {
        return ports.join(', ');  // 如果要在端口号之间添加空格，可以使用 "ports.join(' ')"
      } else if (typeof ports === 'string') {
        // 如果端口作为字符串存储，可以根据具体的分隔符进行拆分
        return ports.split('\n').join(', ');  // 例如，如果是用逗号分隔的字符串，则可以使用.split(',')来拆分
      } else {
        return ports; // 其他情况下，原样返回
      }
    },

    addClick() {
      this.Action = 1;
      this.$nextTick(() => {
        this.accountForm = {
          IsValid: 1,
          DeviceObjType: 1,
          CheckType: 1,
          Interval: 60,
          DeviceObj: []
        };
        this.dialogVisible = true;
        // 等待 dialog 显示并渲染 el-form 后再 reset
        if (this.$refs['accountForm']) {
          this.$refs['accountForm'].resetFields();
        }
      });
    },
    validateInput() {
      // 使用正则表达式验证输入，允许整数和换行
      this.accountForm.Port = this.accountForm.Port.replace(/[^\d\n]/g, "");

      // // 验证输入是否在范围内
      // const port = parseInt(this.accountForm.Port);
      // if (isNaN(port) || port < 1 || port > 65535) {
      //     // 输入不在范围内，进行相应处理，例如给出提示信息
      //     // console.log("端口号必须是介于 1 到 65535 之间的整数");
      // }
    },

    changeClick(row, index) {
      if (Array.isArray(row.Port))
        row.Port = row.Port.join('\n')
      this.Action = 2
      this.$nextTick(() => {
        this.accountForm = { ...row }
        this.$refs['accountForm'].resetFields();
      })
      this.dialogVisible = true
    },
    deleteClick(row) {
      this.$confirm('此操作将永久删除该规则, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        let data = {
          Data: {
            Action: 3,
            Detail: { ...row }
          }
        }
        const res = await connrequest('EditListenPortRule', data)
        if (res.Status.StatusCode === 0) {
          this.$message({
            type: 'success',
            message: '删除成功!'
          });
          this.getData()
          this.dialogVisible = false
        }
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      });
    },
    submit() {
      this.$refs['accountForm'].validate(async (valid) => {
        if (valid) {
          if (this.accountForm.DeviceObjType === 2) {
            if (!this.accountForm.DeviceObj || this.accountForm?.DeviceObj?.length === 0) {
              this.$message.error('请选择部门')
              return false
            }
          }
          if (this.accountForm.DeviceObjType === 8) {
            if (!this.accountForm.DeviceObj || this.accountForm?.DeviceObj?.length === 0) {
              this.$message.error('请选择角色')
              return false
            }
          }
          if (this.accountForm.DeviceObjType === 6) {
            if (!this.accountForm.DeviceObj || this.accountForm?.DeviceObj?.length === 0) {
              this.$message.error('请选择资产')
              return false
            }
          }
          if (this.accountForm.Interval * 1 < 1) {
            this.$message.error('检测间隔必须为大于0的整数')
            return false
          }
          let data = {
            Data: {
              Action: this.Action,
              Detail: { ...this.accountForm, Port: this.accountForm.Port != undefined ? this.accountForm.Port.split('\n').map(item => parseInt(item, 10)).filter(value => !isNaN(value)) : [] }
            }
          }
          const res = await connrequest('EditListenPortRule', data)
          if (res.Status.StatusCode === 0) {
            this.$message.success(this.Action == 1 ? '添加成功' : '修改成功')
            this.getData()
            this.dialogVisible = false
          }
        }
      })
    }
  }
}
</script>